package com.sz.virtualbank.service.finance.impl;

import com.sz.virtualbank.common.exception.BusinessException;
import com.sz.virtualbank.dao.entity.FinancialProduct;
import com.sz.virtualbank.dao.entity.InvestmentOrder;
import com.sz.virtualbank.dao.entity.User;
import com.sz.virtualbank.dao.mapper.FinancialProductMapper;
import com.sz.virtualbank.dao.mapper.InvestmentOrderMapper;
import com.sz.virtualbank.dao.mapper.UserMapper;
import com.sz.virtualbank.service.account.AccountService;
import com.sz.virtualbank.service.finance.FinanceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

/**
 * 理财服务实现类
 * 
 * @author Claude
 */
@Service
@Slf4j
public class FinanceServiceImpl implements FinanceService {

    @Autowired
    private FinancialProductMapper financialProductMapper;
    
    @Autowired
    private InvestmentOrderMapper investmentOrderMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private AccountService accountService;
    
    @Override
    public Map<String, Object> getProductList(Integer riskLevel, Integer minDuration, Integer maxDuration, 
                                             BigDecimal minReturn, Integer status, Integer page, Integer size) {
        if (page == null || page < 1) {
            page = 1;
        }
        
        if (size == null || size < 1) {
            size = 10;
        }
        
        int offset = (page - 1) * size;
        
        // 查询产品列表
        List<FinancialProduct> products = financialProductMapper.selectProducts(
                riskLevel, minDuration, maxDuration, minReturn, status, offset, size);
        
        // 查询总记录数
        int total = financialProductMapper.countProducts(riskLevel, minDuration, maxDuration, minReturn, status);
        
        // 计算每个产品的销售进度
        List<Map<String, Object>> productsList = new ArrayList<>();
        for (FinancialProduct product : products) {
            Map<String, Object> productMap = new HashMap<>();
            // 转换产品对象为Map
            productMap.put("id", product.getId());
            productMap.put("productName", product.getProductName());
            productMap.put("productCode", product.getProductCode());
            productMap.put("expectedReturn", product.getExpectedReturn());
            productMap.put("minAmount", product.getMinAmount());
            productMap.put("maxAmount", product.getMaxAmount());
            productMap.put("duration", product.getDuration());
            productMap.put("riskLevel", product.getRiskLevel());
            productMap.put("productDesc", product.getProductDesc());
            productMap.put("status", product.getStatus());
            productMap.put("startTime", product.getStartTime());
            productMap.put("endTime", product.getEndTime());
            productMap.put("valueDate", product.getValueDate());
            productMap.put("dueDate", product.getDueDate());
            productMap.put("totalAmount", product.getTotalAmount());
            productMap.put("soldAmount", product.getSoldAmount());
            
            // 设置销售进度百分比
            if (product.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal soldPercentage = product.getSoldAmount()
                        .multiply(new BigDecimal("100"))
                        .divide(product.getTotalAmount(), 2, RoundingMode.HALF_UP);
                productMap.put("soldPercentage", soldPercentage);
            } else {
                productMap.put("soldPercentage", BigDecimal.ZERO);
            }
            
            productsList.add(productMap);
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("list", productsList);
        
        return result;
    }

    @Override
    public FinancialProduct getProductDetail(Long id) {
        FinancialProduct product = financialProductMapper.selectById(id);
        
        if (product == null) {
            throw new BusinessException("理财产品不存在");
        }
        
        return product;
    }

    @Override
    public Map<String, Object> getHotProducts(Integer limit) {
        if (limit == null || limit < 1) {
            limit = 5;
        }
        
        List<FinancialProduct> products = financialProductMapper.selectHotProducts(limit);
        
        // 计算每个产品的销售进度
        List<Map<String, Object>> productsList = new ArrayList<>();
        for (FinancialProduct product : products) {
            Map<String, Object> productMap = new HashMap<>();
            // 转换产品对象为Map
            productMap.put("id", product.getId());
            productMap.put("productName", product.getProductName());
            productMap.put("productCode", product.getProductCode());
            productMap.put("expectedReturn", product.getExpectedReturn());
            productMap.put("minAmount", product.getMinAmount());
            productMap.put("maxAmount", product.getMaxAmount());
            productMap.put("duration", product.getDuration());
            productMap.put("riskLevel", product.getRiskLevel());
            productMap.put("productDesc", product.getProductDesc());
            productMap.put("status", product.getStatus());
            productMap.put("startTime", product.getStartTime());
            productMap.put("endTime", product.getEndTime());
            productMap.put("valueDate", product.getValueDate());
            productMap.put("dueDate", product.getDueDate());
            productMap.put("totalAmount", product.getTotalAmount());
            productMap.put("soldAmount", product.getSoldAmount());
            
            // 设置销售进度百分比
            if (product.getTotalAmount().compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal soldPercentage = product.getSoldAmount()
                        .multiply(new BigDecimal("100"))
                        .divide(product.getTotalAmount(), 2, RoundingMode.HALF_UP);
                productMap.put("soldPercentage", soldPercentage);
            } else {
                productMap.put("soldPercentage", BigDecimal.ZERO);
            }
            
            productsList.add(productMap);
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("list", productsList);
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public InvestmentOrder purchaseProduct(Long userId, Long productId, BigDecimal amount, String paymentPassword) {
        // 验证支付密码
        if (!accountService.verifyPayPassword(userId, paymentPassword)) {
            throw new BusinessException("支付密码错误");
        }
        
        // 获取用户信息
        User user = userMapper.selectById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        
        // 获取产品信息
        FinancialProduct product = financialProductMapper.selectById(productId);
        if (product == null) {
            throw new BusinessException("理财产品不存在");
        }
        
        // 检查产品状态
        if (product.getStatus() != 1) {
            throw new BusinessException("当前产品不可购买");
        }
        
        // 检查当前时间是否在销售期
        LocalDateTime now = LocalDateTime.now();
        if (now.isBefore(product.getStartTime()) || now.isAfter(product.getEndTime())) {
            throw new BusinessException("不在产品销售期内");
        }
        
        // 检查投资金额
        if (amount.compareTo(product.getMinAmount()) < 0) {
            throw new BusinessException("投资金额不能低于最低起投金额");
        }
        
        if (product.getMaxAmount() != null && amount.compareTo(product.getMaxAmount()) > 0) {
            throw new BusinessException("投资金额不能高于最高投资限额");
        }
        
        // 检查剩余可投金额
        BigDecimal remainingAmount = product.getTotalAmount().subtract(product.getSoldAmount());
        if (amount.compareTo(remainingAmount) > 0) {
            throw new BusinessException("超出产品剩余可投金额");
        }
        
        // 从账户扣款
        String tradeNo = accountService.pay(userId, amount, "INVESTMENT", productId);
        
        // 更新产品已售金额
        financialProductMapper.increaseSoldAmount(productId, amount);
        
        // 计算预期收益
        BigDecimal expectedReturn = product.getExpectedReturn()
                .divide(new BigDecimal("100"), 8, RoundingMode.HALF_UP); // 转换为小数
        BigDecimal days = new BigDecimal(product.getDuration());
        BigDecimal expectedProfit = amount.multiply(expectedReturn)
                .multiply(days)
                .divide(new BigDecimal("365"), 2, RoundingMode.HALF_UP);
        
        // 创建投资订单
        InvestmentOrder order = new InvestmentOrder();
        order.setOrderNo(generateOrderNo());
        order.setUserId(userId);
        order.setProductId(productId);
        order.setAmount(amount);
        order.setExpectedProfit(expectedProfit);
        order.setStatus(0); // 处理中
        order.setPurchaseTime(now);
        // 起息时间和到期时间将在审核通过后设置
        order.setCreateTime(now);
        order.setUpdateTime(now);
        
        investmentOrderMapper.insert(order);
        
        // 更新订单状态为已生效（实际应用中可能需要后台审核）
        order.setStatus(1); // 已生效
        order.setValueTime(product.getValueDate().atStartOfDay());
        order.setDueTime(product.getDueDate().atStartOfDay());
        
        investmentOrderMapper.update(order);
        
        return order;
    }

    @Override
    public Map<String, Object> getInvestmentOrderList(Long userId, Integer status, Integer page, Integer size) {
        if (page == null || page < 1) {
            page = 1;
        }
        
        if (size == null || size < 1) {
            size = 10;
        }
        
        int offset = (page - 1) * size;
        
        // 查询投资订单列表
        List<InvestmentOrder> orders = investmentOrderMapper.selectByUserId(userId, status, offset, size);
        
        // 查询总记录数
        int total = investmentOrderMapper.countByUserId(userId, status);
        
        // 查询每个订单关联的产品名称
        List<Map<String, Object>> orderList = new ArrayList<>();
        for (InvestmentOrder order : orders) {
            Map<String, Object> orderMap = new HashMap<>();
            // 转换订单对象为Map
            orderMap.put("id", order.getId());
            orderMap.put("orderNo", order.getOrderNo());
            orderMap.put("userId", order.getUserId());
            orderMap.put("productId", order.getProductId());
            orderMap.put("amount", order.getAmount());
            orderMap.put("expectedProfit", order.getExpectedProfit());
            orderMap.put("actualProfit", order.getActualProfit());
            orderMap.put("status", order.getStatus());
            orderMap.put("purchaseTime", order.getPurchaseTime());
            orderMap.put("valueTime", order.getValueTime());
            orderMap.put("dueTime", order.getDueTime());
            orderMap.put("profitReceivedTime", order.getProfitReceivedTime());
            
            // 查询关联的产品信息
            FinancialProduct product = financialProductMapper.selectById(order.getProductId());
            if (product != null) {
                orderMap.put("productName", product.getProductName());
                orderMap.put("productCode", product.getProductCode());
                orderMap.put("expectedReturn", product.getExpectedReturn());
                orderMap.put("duration", product.getDuration());
                orderMap.put("riskLevel", product.getRiskLevel());
            }
            
            orderList.add(orderMap);
        }
        
        Map<String, Object> result = new HashMap<>();
        result.put("total", total);
        result.put("list", orderList);
        
        return result;
    }

    @Override
    public Map<String, Object> getInvestmentOrderDetail(Long id, Long userId) {
        InvestmentOrder order = investmentOrderMapper.selectById(id);
        
        // 验证订单是否存在及归属权
        if (order == null || !order.getUserId().equals(userId)) {
            throw new BusinessException("投资订单不存在或不属于当前用户");
        }
        
        // 获取产品信息
        FinancialProduct product = financialProductMapper.selectById(order.getProductId());
        
        Map<String, Object> result = new HashMap<>();
        result.put("order", order);
        result.put("product", product);
        
        return result;
    }

    @Override
    public Map<String, BigDecimal> getInvestmentSummary(Long userId) {
        // 获取用户所有投资订单
        List<InvestmentOrder> orders = investmentOrderMapper.selectByUserId(userId, null, 0, Integer.MAX_VALUE);
        
        BigDecimal totalInvestment = BigDecimal.ZERO; // 总投资
        BigDecimal inProgressAmount = BigDecimal.ZERO; // 进行中投资
        BigDecimal totalProfit = BigDecimal.ZERO; // 总收益（实际）
        BigDecimal expectedProfit = BigDecimal.ZERO; // 预期收益（进行中）
        
        for (InvestmentOrder order : orders) {
            if (order.getStatus() == 1) { // 进行中
                inProgressAmount = inProgressAmount.add(order.getAmount());
                expectedProfit = expectedProfit.add(order.getExpectedProfit());
            } else if (order.getStatus() == 2) { // 已到期
                totalProfit = totalProfit.add(order.getActualProfit() != null ? order.getActualProfit() : BigDecimal.ZERO);
            }
            
            // 总投资累加所有状态的订单金额
            totalInvestment = totalInvestment.add(order.getAmount());
        }
        
        Map<String, BigDecimal> result = new HashMap<>();
        result.put("totalInvestment", totalInvestment);
        result.put("inProgressAmount", inProgressAmount);
        result.put("totalProfit", totalProfit);
        result.put("expectedProfit", expectedProfit);
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinancialProduct createProduct(FinancialProduct product) {
        // 检查产品代码是否已存在
        FinancialProduct existingProduct = financialProductMapper.selectByProductCode(product.getProductCode());
        if (existingProduct != null) {
            throw new BusinessException("产品代码已存在");
        }
        
        // 设置创建时间和更新时间
        LocalDateTime now = LocalDateTime.now();
        product.setCreateTime(now);
        product.setUpdateTime(now);
        
        // 初始化已售金额
        product.setSoldAmount(BigDecimal.ZERO);
        
        // 保存产品
        financialProductMapper.insert(product);
        
        return product;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public FinancialProduct updateProduct(FinancialProduct product) {
        // 获取原产品信息
        FinancialProduct existingProduct = financialProductMapper.selectById(product.getId());
        if (existingProduct == null) {
            throw new BusinessException("理财产品不存在");
        }
        
        // 如果已有订单，某些字段不能修改
        if (existingProduct.getSoldAmount().compareTo(BigDecimal.ZERO) > 0) {
            // 保持原有值不变
            product.setProductCode(existingProduct.getProductCode());
            product.setExpectedReturn(existingProduct.getExpectedReturn());
            product.setDuration(existingProduct.getDuration());
            product.setTotalAmount(existingProduct.getTotalAmount());
            product.setSoldAmount(existingProduct.getSoldAmount());
            product.setValueDate(existingProduct.getValueDate());
            product.setDueDate(existingProduct.getDueDate());
        }
        
        // 更新时间
        product.setUpdateTime(LocalDateTime.now());
        
        // 更新产品
        financialProductMapper.update(product);
        
        return product;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProductStatus(Long id, Integer status) {
        // 获取产品信息
        FinancialProduct product = financialProductMapper.selectById(id);
        if (product == null) {
            throw new BusinessException("理财产品不存在");
        }
        
        // 某些状态转换需要特殊处理
        if (status == 3 && product.getStatus() == 1) { // 从发售中到已到期
            // 处理所有相关订单
            List<InvestmentOrder> orders = investmentOrderMapper.selectByProductId(id);
            for (InvestmentOrder order : orders) {
                if (order.getStatus() == 1) { // 进行中的订单
                    // 计算实际收益（示例中按预期收益计算）
                    BigDecimal actualProfit = order.getExpectedProfit();
                    
                    // 更新订单状态和实际收益
                    investmentOrderMapper.updateProfit(order.getId(), actualProfit);
                    
                    // 向用户账户返还本金和收益
                    accountService.recharge(order.getUserId(), 
                            order.getAmount().add(actualProfit), 
                            "INVESTMENT_RETURN", 
                            order.getOrderNo());
                }
            }
        }
        
        // 更新产品状态
        return financialProductMapper.updateStatus(id, status) > 0;
    }
    
    /**
     * 生成订单编号
     *
     * @return 订单编号
     */
    private String generateOrderNo() {
        // 格式：I + 时间戳 + 随机数
        return "I" + System.currentTimeMillis() + String.format("%04d", (int) (Math.random() * 10000));
    }
}
